﻿/*
 *  Date:2015/8/4
 *  Author: huang hao
 */

using System;

namespace IceCS.Puke.Core
{
    /// <summary>
    /// 表示一张标准的扑克牌，花色包含Club(梅花)、Diamond(方块)、Heart(红心)、Spade(黑桃)，从A到K。
    /// </summary>
    public partial class Card : ICloneable, IComparable<Card>, IComparable
    {
        #region 属性
        /// <summary>
        /// 花色
        /// </summary>
        public Suit Suit { get; }
        /// <summary>
        /// 牌面数字
        /// </summary>
        public Rank Rank { get; }
        #endregion

        #region 构造函数
        /// <summary>
        /// 默认构造函数
        /// </summary>
        private Card() { }

        public Card(Suit suit, Rank rank)
        {
            this.Suit = suit;
            this.Rank = rank;
        }

        #endregion

        #region 实现 ICloneable 接口

        /// <summary>
        /// 对Card对象进行复制(浅复制)
        /// </summary>
        /// <returns>对象的副本</returns>
        public object Clone()
        {
            return MemberwiseClone();
        }

        #endregion

        /// <summary>
        /// 对Card对象进行复制(浅复制)
        /// </summary>
        /// <returns></returns>
        public Card CloneCard()
        {
            return Clone() as Card;
        }

        #region 实现 IComparable 接口
        /// <summary>
        ///   将当前实例与同一类型的另一个对象进行比较，并返回一个整数，该整数指示当前实
        ///   例在排序顺序中的位置是位于另一个对象之前、之后还是与其位置相同。
        /// </summary>
        /// <param name="obj">与此实例进行比较的对象。</param>
        /// <returns>
        /// 一个值，指示要比较的对象的相对顺序。
        ///  返回值的含义如下：
        ///         值
        ///         含义
        ///         小于零
        ///         此实例在排序顺序中位于 <paramref name="obj" /> 之前。
        ///         零
        ///         此实例在排序顺序中的同一位置中发生<paramref name="obj" />。
        ///         大于零
        ///         此实例在排序顺序中位于 <paramref name="obj" /> 之后。
        ///       </returns>
        /// <exception cref="T:System.ArgumentException">
        ///   <paramref name="obj" />不是与此实例相同的类型。
        /// </exception>
        public int CompareTo(object obj)
        {
            return CompareTo((Card)obj);
        }

        #endregion

        #region 实现 IComparable<Card> 接口
        /// <summary>
        ///   将当前实例与同一类型的另一个对象进行比较，并返回一个整数，该整数指示当
        ///   前实例在排序顺序中的位置是位于另一个对象之前、之后还是与其位置相同。
        /// </summary>
        /// <param name="card">与此实例进行比较的对象。</param>
        /// <returns>
        /// 一个值，指示要比较的对象的相对顺序。
        ///  返回值的含义如下：
        ///         值
        ///         含义
        ///         小于零
        ///         此实例在排序顺序中位于 <paramref name="card" /> 之前。
        ///         零
        ///         此实例中出现的相同位置在排序顺序中是 <paramref name="card" />。
        ///         大于零
        ///         此实例在排序顺序中位于 <paramref name="card" /> 之后。
        /// </returns>
        public int CompareTo(Card card)
        {
            return GetHashCode() - card.GetHashCode();
        }

        #endregion

        /// <summary>
        /// 重载 GetHashCode
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode() => ((int)Suit - 1) * 13 + (int)Rank;

        /// <summary>
        /// 重写ToString方法
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return "The " + Rank + " of " + Suit + "s"; ;
        }

        /// <summary>
        /// 输出中文
        /// </summary>
        /// <returns></returns>
        public string ToChineseString()
        {
            string[] suitArr = { "梅花", "方块", "红桃", "黑桃" };
            string[] rankArr = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
            return $"{suitArr[(int)Suit - 1]} {rankArr[(int)Rank - 1]}";
        }
    }
}
